<!DOCTYPE html>
<html lang=zh>
<head>
    <!-- so meta -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="HandheldFriendly" content="True">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5" />
    <meta name="description" content="class关键字在ES6之前，我们都是使用的构造函数的形式来创建自定义类型的对象 1234function Foo(bar) &amp;#123;  this.bar &#x3D; bar&amp;#125;var foo &#x3D; new FOo(&amp;#x27;curry&amp;#x27;)  ES6为我们提供了一种新的语法，使用 class 关键字来创建类，但它的本质依旧是构造函数，class 关键字只是一种语法糖而已。 如何定义类">
<meta property="og:type" content="article">
<meta property="og:title" content="ES6">
<meta property="og:url" content="https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/index.html">
<meta property="og:site_name" content="柯里的语法糖">
<meta property="og:description" content="class关键字在ES6之前，我们都是使用的构造函数的形式来创建自定义类型的对象 1234function Foo(bar) &amp;#123;  this.bar &#x3D; bar&amp;#125;var foo &#x3D; new FOo(&amp;#x27;curry&amp;#x27;)  ES6为我们提供了一种新的语法，使用 class 关键字来创建类，但它的本质依旧是构造函数，class 关键字只是一种语法糖而已。 如何定义类">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20211208172052795.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20211208230549399.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20211208230722876.png">
<meta property="article:published_time" content="2022-02-05T06:19:40.049Z">
<meta property="article:modified_time" content="2022-02-05T06:19:40.049Z">
<meta property="article:author" content="柯里的语法糖">
<meta property="article:tag" content="JavaScript">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20211208172052795.png">
    
    
      
        
          <link rel="shortcut icon" href="https://codertzm.oss-cn-chengdu.aliyuncs.com/favicon.ico">
        
      
      
        
          <link rel="icon" type="image/png" href="https://codertzm.oss-cn-chengdu.aliyuncs.com/favicon.ico" sizes="192x192">
        
      
      
        
          <link rel="apple-touch-icon" sizes="180x180" href="https://codertzm.oss-cn-chengdu.aliyuncs.com/favicon.ico">
        
      
    
    <!-- title -->
    <title>ES6</title>
    <!-- styles -->
    
<link rel="stylesheet" href="/css/style.css">

    <!-- persian styles -->
    
    <!-- rss -->
    
    
	<!-- mathjax -->
	
<meta name="generator" content="Hexo 6.0.0"></head>

<body class="max-width mx-auto px3 ltr">
    
      <div id="header-post">
  <a id="menu-icon" href="#" aria-label="Menu"><i class="fas fa-bars fa-lg"></i></a>
  <a id="menu-icon-tablet" href="#" aria-label="Menu"><i class="fas fa-bars fa-lg"></i></a>
  <a id="top-icon-tablet" href="#" aria-label="Top" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');" style="display:none;"><i class="fas fa-chevron-up fa-lg"></i></a>
  <span id="menu">
    <span id="nav">
      <ul>
        <!--
       --><li><a href="/">首页</a></li><!--
     --><!--
       --><li><a href="/tags/">标签</a></li><!--
     --><!--
       --><li><a href="/categories/">分类</a></li><!--
     --><!--
       --><li><a href="/archives/">归档</a></li><!--
     --><!--
       --><li><a target="_blank" rel="noopener" href="http://github.com/twitzz">项目</a></li><!--
     --><!--
       --><li><a href="/about/">关于</a></li><!--
     --><!--
       --><li><a href="/search/">搜索</a></li><!--
     -->
      </ul>
    </span>
    <br/>
    <span id="actions">
      <ul>
        
        <li><a class="icon" aria-label="上一篇" href="/2022/02/05/JavaScript/Promise/"><i class="fas fa-chevron-left" aria-hidden="true" onmouseover="$('#i-prev').toggle();" onmouseout="$('#i-prev').toggle();"></i></a></li>
        
        
        <li><a class="icon" aria-label="下一篇" href="/2022/02/05/JavaScript/ES6+/"><i class="fas fa-chevron-right" aria-hidden="true" onmouseover="$('#i-next').toggle();" onmouseout="$('#i-next').toggle();"></i></a></li>
        
        <li><a class="icon" aria-label="返回顶部" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fas fa-chevron-up" aria-hidden="true" onmouseover="$('#i-top').toggle();" onmouseout="$('#i-top').toggle();"></i></a></li>
        <li><a class="icon" aria-label="分享文章" href="#"><i class="fas fa-share-alt" aria-hidden="true" onmouseover="$('#i-share').toggle();" onmouseout="$('#i-share').toggle();" onclick="$('#share').toggle();return false;"></i></a></li>
      </ul>
      <span id="i-prev" class="info" style="display:none;">上一篇</span>
      <span id="i-next" class="info" style="display:none;">下一篇</span>
      <span id="i-top" class="info" style="display:none;">返回顶部</span>
      <span id="i-share" class="info" style="display:none;">分享文章</span>
    </span>
    <br/>
    <div id="share" style="display: none">
      <ul>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/"><i class="fab fa-facebook " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&text=ES6"><i class="fab fa-twitter " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-linkedin " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&is_video=false&description=ES6"><i class="fab fa-pinterest " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=ES6&body=Check out this article: https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/"><i class="fas fa-envelope " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-get-pocket " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-reddit " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-stumbleupon " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-digg " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&name=ES6&description="><i class="fab fa-tumblr " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&t=ES6"><i class="fab fa-hacker-news " aria-hidden="true"></i></a></li>
</ul>

    </div>
    <div id="toc">
      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#class%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">1.</span> <span class="toc-text">class关键字</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E5%AE%9A%E4%B9%89%E7%B1%BB"><span class="toc-number">1.1.</span> <span class="toc-text">如何定义类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0"><span class="toc-number">1.2.</span> <span class="toc-text">类的构造函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E5%AE%9E%E4%BE%8B%E6%96%B9%E6%B3%95"><span class="toc-number">1.3.</span> <span class="toc-text">类的实例方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E8%AE%BF%E9%97%AE%E5%99%A8%E6%96%B9%E6%B3%95"><span class="toc-number">1.4.</span> <span class="toc-text">类的访问器方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.</span> <span class="toc-text">类的静态方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#ES6%E4%B8%AD%E7%B1%BB%E7%9A%84%E7%BB%A7%E6%89%BF%EF%BC%88extends%EF%BC%89"><span class="toc-number">1.6.</span> <span class="toc-text">ES6中类的继承（extends）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#super%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">1.7.</span> <span class="toc-text">super关键字</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%A7%E6%89%BF%E5%86%85%E7%BD%AE%E7%B1%BB"><span class="toc-number">1.8.</span> <span class="toc-text">继承内置类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E6%B7%B7%E5%85%A5%EF%BC%88mixin%EF%BC%89"><span class="toc-number">1.9.</span> <span class="toc-text">类的混入（mixin）</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AD%97%E9%9D%A2%E9%87%8F%E7%9A%84%E5%A2%9E%E5%BC%BA"><span class="toc-number">2.</span> <span class="toc-text">字面量的增强</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%9E%E6%80%A7%E7%9A%84%E7%AE%80%E5%86%99"><span class="toc-number">2.1.</span> <span class="toc-text">属性的简写</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%96%B9%E6%B3%95%E7%9A%84%E7%AE%80%E5%86%99"><span class="toc-number">2.2.</span> <span class="toc-text">方法的简写</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7%E5%90%8D"><span class="toc-number">2.3.</span> <span class="toc-text">计算属性名</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A7%A3%E6%9E%84"><span class="toc-number">3.</span> <span class="toc-text">解构</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E7%BB%84%E7%9A%84%E8%A7%A3%E6%9E%84"><span class="toc-number">3.1.</span> <span class="toc-text">数组的解构</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E7%9A%84%E8%A7%A3%E6%9E%84"><span class="toc-number">3.2.</span> <span class="toc-text">对象的解构</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#let%E4%B8%8Econst"><span class="toc-number">4.</span> <span class="toc-text">let与const</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#let%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">4.1.</span> <span class="toc-text">let关键字</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#const%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">4.2.</span> <span class="toc-text">const关键字</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#let%E4%B8%8Econst%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%8F%90%E5%8D%87"><span class="toc-number">4.3.</span> <span class="toc-text">let与const的作用域提升</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#window%E5%AF%B9%E8%B1%A1%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7"><span class="toc-number">4.4.</span> <span class="toc-text">window对象添加属性</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9D%97%E7%BA%A7%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">4.5.</span> <span class="toc-text">块级作用域</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9A%82%E6%97%B6%E6%80%A7%E6%AD%BB%E5%8C%BA"><span class="toc-number">4.6.</span> <span class="toc-text">暂时性死区</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A8%A1%E6%9D%BF%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-number">5.</span> <span class="toc-text">模板字符串</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A0%87%E7%AD%BE%E6%A8%A1%E6%9D%BF%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-number">5.1.</span> <span class="toc-text">标签模板字符串</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%9B%B8%E5%85%B3"><span class="toc-number">6.</span> <span class="toc-text">函数相关</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%BB%98%E8%AE%A4%E5%8F%82%E6%95%B0"><span class="toc-number">6.1.</span> <span class="toc-text">默认参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0"><span class="toc-number">6.2.</span> <span class="toc-text">剩余参数</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0%E5%92%8Carguments%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">6.2.1.</span> <span class="toc-text">剩余参数和arguments的区别</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0"><span class="toc-number">6.3.</span> <span class="toc-text">箭头函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%95%E5%BC%80%E8%AF%AD%E6%B3%95"><span class="toc-number">6.4.</span> <span class="toc-text">展开语法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%B0%E5%80%BC%E7%9A%84%E8%A1%A8%E7%A4%BA"><span class="toc-number">7.</span> <span class="toc-text">数值的表示</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Symbol"><span class="toc-number">8.</span> <span class="toc-text">Symbol</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Set"><span class="toc-number">9.</span> <span class="toc-text">Set</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9B%E5%BB%BASet"><span class="toc-number">9.1.</span> <span class="toc-text">创建Set</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E7%BB%84%E5%8E%BB%E9%87%8D"><span class="toc-number">9.2.</span> <span class="toc-text">数组去重</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Set%E5%B8%B8%E8%A7%81%E7%9A%84%E5%B1%9E%E6%80%A7%E5%92%8C%E6%96%B9%E6%B3%95"><span class="toc-number">9.3.</span> <span class="toc-text">Set常见的属性和方法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E8%A7%81%E5%B1%9E%E6%80%A7"><span class="toc-number">9.3.1.</span> <span class="toc-text">常见属性</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E8%A7%81%E6%96%B9%E6%B3%95"><span class="toc-number">9.3.2.</span> <span class="toc-text">常见方法</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#WeakSet"><span class="toc-number">10.</span> <span class="toc-text">WeakSet</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakSet%E5%92%8CSet%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">10.1.</span> <span class="toc-text">WeakSet和Set的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakSet%E4%B8%AD%E5%AF%B9%E5%85%83%E7%B4%A0%E7%9A%84%E5%BC%95%E7%94%A8%E6%98%AF%E5%BC%B1%E5%BC%95%E7%94%A8"><span class="toc-number">10.2.</span> <span class="toc-text">WeakSet中对元素的引用是弱引用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakSet%E7%9A%84%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">10.3.</span> <span class="toc-text">WeakSet的应用场景</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Map"><span class="toc-number">11.</span> <span class="toc-text">Map</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Map%E4%B8%8E%E6%99%AE%E9%80%9A%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">11.1.</span> <span class="toc-text">Map与普通对象的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Map%E7%9A%84%E5%B8%B8%E8%A7%81%E5%B1%9E%E6%80%A7%E5%92%8C%E6%96%B9%E6%B3%95"><span class="toc-number">11.2.</span> <span class="toc-text">Map的常见属性和方法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E8%A7%81%E5%B1%9E%E6%80%A7-1"><span class="toc-number">11.2.1.</span> <span class="toc-text">常见属性</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E8%A7%81%E6%96%B9%E6%B3%95-1"><span class="toc-number">11.2.2.</span> <span class="toc-text">常见方法</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#WeakMap"><span class="toc-number">12.</span> <span class="toc-text">WeakMap</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakMap%E5%92%8CMap%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">12.1.</span> <span class="toc-text">WeakMap和Map的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakMap%E7%9A%84%E5%B8%B8%E8%A7%81%E6%96%B9%E6%B3%95"><span class="toc-number">12.2.</span> <span class="toc-text">WeakMap的常见方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakMap%E7%9A%84%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">12.3.</span> <span class="toc-text">WeakMap的应用场景</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%BB%E7%BB%93"><span class="toc-number">13.</span> <span class="toc-text">总结</span></a></li></ol>
    </div>
  </span>
</div>

    
    <div class="content index py4">
        
        <article class="post" itemscope itemtype="http://schema.org/BlogPosting">
  <header>
    
    <h1 class="posttitle" itemprop="name headline">
        ES6
    </h1>



    <div class="meta">
      <span class="author" itemprop="author" itemscope itemtype="http://schema.org/Person">
        <span itemprop="name">柯里的语法糖</span>
      </span>
      
    <div class="postdate">
      
        <time datetime="2022-02-05T06:19:40.049Z" itemprop="datePublished">2022-02-05</time>
        
      
    </div>


      
    <div class="article-category">
        <i class="fas fa-archive"></i>
        <a class="category-link" href="/categories/%E5%89%8D%E7%AB%AF%E5%9F%BA%E7%A1%80/">前端基础</a>
    </div>


      
    <div class="article-tag">
        <i class="fas fa-tag"></i>
        <a class="tag-link-link" href="/tags/JavaScript/" rel="tag">JavaScript</a>
    </div>


    </div>
  </header>
  

  <div class="content" itemprop="articleBody">
    <h2 id="class关键字"><a href="#class关键字" class="headerlink" title="class关键字"></a>class关键字</h2><p>在ES6之前，我们都是使用的构造函数的形式来创建自定义类型的对象</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Foo</span>(<span class="params">bar</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">this</span>.bar = bar</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> foo = <span class="keyword">new</span> FOo(<span class="string">&#x27;curry&#x27;</span>)</span><br></pre></td></tr></table></figure>

<p>ES6为我们提供了一种新的语法，使用 <code>class</code> 关键字来创建类，但它的本质依旧是构造函数，<code>class</code> 关键字只是一种语法糖而已。</p>
<h3 id="如何定义类"><a href="#如何定义类" class="headerlink" title="如何定义类"></a>如何定义类</h3><p>类的声明有两种方式：类声明和类表达式</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 类声明</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 表达式</span></span><br><span class="line"><span class="keyword">var</span> Foo = <span class="class"><span class="keyword">class</span> </span>&#123;</span><br><span class="line">  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="类的构造函数"><a href="#类的构造函数" class="headerlink" title="类的构造函数"></a>类的构造函数</h3><p>如果我们希望在创建对象的时候给类传递一些参数，这个时候应该如何做？</p>
<p>在<code>class</code>中有一个叫做 <code>constructor</code>（名称固定）的构造函数，当我们通过<code>new</code>关键字创建一个类的时候，就会调用这个类的 <code>constructor</code> 方法。</p>
<blockquote>
<p>每个类中只能有一个 <code>constructor</code> 方法，否则会抛出异常</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">bar</span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.bar = bar</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="类的实例方法"><a href="#类的实例方法" class="headerlink" title="类的实例方法"></a>类的实例方法</h3><p>通过<code>constructor</code>方法将对象的属性绑定在实例对象上，但是对于方法而言，我们希望将它们放在原型上。我们可以直接将方法写在类中，作为原型的方法。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">bar</span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.bar = bar</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="title">running</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="built_in">this</span>.bar + <span class="string">&#x27;running&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="类的访问器方法"><a href="#类的访问器方法" class="headerlink" title="类的访问器方法"></a>类的访问器方法</h3><p>类中也是有访问器方法的。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">bar</span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>._bar = bar</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="title">running</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="built_in">this</span>.bar + <span class="string">&#x27;running&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">set</span> <span class="title">bar</span>(<span class="params">newBar</span>)&#123;</span><br><span class="line">    <span class="built_in">this</span>._bar = newBar</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">get</span> <span class="title">bar</span>()&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&#x27;123&#x27;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="类的静态方法"><a href="#类的静态方法" class="headerlink" title="类的静态方法"></a>类的静态方法</h3><p>我们可以在类上直接定义方法，这样的方法被称为静态方法</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">age</span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.age = age</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">static</span> <span class="function"><span class="title">createPerson</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> Person(<span class="built_in">Math</span>.floor(<span class="built_in">Math</span>.random()*<span class="number">100</span>+<span class="number">1</span>))</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="ES6中类的继承（extends）"><a href="#ES6中类的继承（extends）" class="headerlink" title="ES6中类的继承（extends）"></a>ES6中类的继承（extends）</h3><p>在ES6之前，如果我们需要实现继承，需要自己创建函数，使用 <strong>寄生组合式继承</strong> 来实现，但ES6为我们提供了 <code>extends</code> 关键字，它也仅仅是一种语法糖而已，内部实现的方式其实就是寄生组合式继承。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">age</span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.age = age</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 继承</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Coder</span> <span class="keyword">extends</span> <span class="title">Person</span></span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="super关键字"><a href="#super关键字" class="headerlink" title="super关键字"></a>super关键字</h3><p>在子（派生）类的构造函数中使用<code>this</code>或者返回默认对象之前，必须先通过 <code>super</code> 调用父类的构造函数。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 继承</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Coder</span> <span class="keyword">extends</span> <span class="title">Person</span></span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">lang,age</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">super</span>(age)</span><br><span class="line">    <span class="built_in">this</span>.lang =lang</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>super</code> 关键字只能用在：子类的构造函数、实例方法、静态方法。</p>
<p>因此，我们可以通过 <code>super</code> 关键字复用父类中的方法，在子类中来对其进行重写。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">age</span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.age = age</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="title">personMethod</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="built_in">this</span>.age)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">static</span> <span class="function"><span class="title">personStaticMethod</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;a person&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Coder</span> <span class="keyword">extends</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">lang,age</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">super</span>(age)</span><br><span class="line">    <span class="built_in">this</span>.lang = lang</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 重写父类方法</span></span><br><span class="line">  <span class="function"><span class="title">personMethod</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="comment">// 复用父类代码</span></span><br><span class="line">    <span class="built_in">super</span>.personMethod()</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="built_in">this</span>.lang)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 重写父类静态方法</span></span><br><span class="line">  <span class="keyword">static</span> <span class="function"><span class="title">personStaticMethod</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="comment">// 复用父类代码</span></span><br><span class="line">    <span class="built_in">super</span>.personStaticMethod()</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;a coder&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="继承内置类"><a href="#继承内置类" class="headerlink" title="继承内置类"></a>继承内置类</h3><p>我们可以继承内置类来对其进行扩展。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">myArray</span> <span class="keyword">extends</span> <span class="title">Array</span> </span>&#123;</span><br><span class="line">  lastItem () &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">this</span>[<span class="built_in">this</span>.length - <span class="number">1</span>]</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myarr = <span class="keyword">new</span> myArray(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line">myarr.lastItem() <span class="comment">// 3</span></span><br></pre></td></tr></table></figure>

<h3 id="类的混入（mixin）"><a href="#类的混入（mixin）" class="headerlink" title="类的混入（mixin）"></a>类的混入（mixin）</h3><p>在JavaScript中只能实现单继承，如果我们需要在一个类中添加多个类的方法可以使用 <strong>混入（mixin）</strong> 。这种思想在<code>React</code>的高阶组件中也有体现，这里不细说。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">name</span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.name = name</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">mixinCoder</span>(<span class="params">BaseClass</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="class"><span class="keyword">class</span> <span class="keyword">extends</span> <span class="title">BaseClass</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="title">coding</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">&#x27;coding&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">mixinRunner</span>(<span class="params">BaseClass</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="class"><span class="keyword">class</span> <span class="keyword">extends</span> <span class="title">BaseClass</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="title">running</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">&#x27;running&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 混入</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">NewPerson</span> <span class="keyword">extends</span> <span class="title">mixinRunner</span>(<span class="title">mixinCoder</span>(<span class="title">Person</span>))</span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">name</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">super</span>(name)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = <span class="keyword">new</span> NewPerson(<span class="string">&#x27;curry&#x27;</span>)</span><br><span class="line">p.running() <span class="comment">// running</span></span><br><span class="line">p.coding() <span class="comment">// coding</span></span><br></pre></td></tr></table></figure>

<h2 id="字面量的增强"><a href="#字面量的增强" class="headerlink" title="字面量的增强"></a>字面量的增强</h2><p>ES6中对 <strong>对象字面量</strong> 进行了增强，称之为 Enhanced object literals（增强对象字面量）</p>
<p>字面量的增强主要包括下面几部分： </p>
<p>属性的简写：<strong>Property Shorthand</strong></p>
<p>方法的简写：<strong>Method Shorthand</strong></p>
<p>计算属性名：<strong>Computed Property Names</strong></p>
<h3 id="属性的简写"><a href="#属性的简写" class="headerlink" title="属性的简写"></a>属性的简写</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> name = <span class="string">&#x27;curry&#x27;</span></span><br><span class="line"><span class="keyword">var</span> age = <span class="number">18</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="comment">// ES6之前</span></span><br><span class="line">  <span class="attr">name</span>: name,</span><br><span class="line">  <span class="attr">age</span>: age,</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// ES6</span></span><br><span class="line">  name,</span><br><span class="line">  age,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="方法的简写"><a href="#方法的简写" class="headerlink" title="方法的简写"></a>方法的简写</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="comment">// ES6之前</span></span><br><span class="line">  <span class="attr">foo</span>:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;,</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// ES6</span></span><br><span class="line">  <span class="function"><span class="title">foo</span>(<span class="params"></span>)</span>&#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="计算属性名"><a href="#计算属性名" class="headerlink" title="计算属性名"></a>计算属性名</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> foo = <span class="string">&#x27;curry&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="comment">// 计算属性名</span></span><br><span class="line">  [foo + <span class="string">&#x27;123&#x27;</span>]() &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;bar&#x27;</span>)</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">obj[foo + <span class="string">&#x27;123&#x27;</span>]()</span><br></pre></td></tr></table></figure>

<h2 id="解构"><a href="#解构" class="headerlink" title="解构"></a>解构</h2><p>ES6中新增了一个从数组或对象中方便获取数据的方法，称之为 <strong>解构Destructuring</strong> 。</p>
<p>解构分为两种：数组的解构和对象的解构。</p>
<h3 id="数组的解构"><a href="#数组的解构" class="headerlink" title="数组的解构"></a>数组的解构</h3><ol>
<li><p>基本解构过程</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> names = [<span class="string">&#x27;curry&#x27;</span>, <span class="string">&#x27;james&#x27;</span>, <span class="string">&#x27;harden&#x27;</span>]</span><br><span class="line"><span class="comment">// ES6之前</span></span><br><span class="line"><span class="keyword">var</span> item1 = names[<span class="number">0</span>]</span><br><span class="line"><span class="keyword">var</span> item2 = names[<span class="number">1</span>]</span><br><span class="line"><span class="keyword">var</span> item3 = names[<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment">// ES6</span></span><br><span class="line"><span class="comment">// 数组解构</span></span><br><span class="line"><span class="keyword">var</span> [item1, item2, item3] = names</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> [itemx, ...newNames] = names</span><br><span class="line"><span class="built_in">console</span>.log(newNames)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> [itema, itemb, itemc, itemd = <span class="string">&#x27;kobe&#x27;</span>] = names</span><br></pre></td></tr></table></figure></li>
<li><p>顺序解构</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 解构后面的元素</span></span><br><span class="line"><span class="keyword">var</span> [, , itemz] = names</span><br><span class="line"><span class="built_in">console</span>.log(itemz) <span class="comment">// &#x27;harden&#x27;</span></span><br></pre></td></tr></table></figure></li>
<li><p>解构出数组</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 解构出一个元素,后面的元素放到一个新数组中</span></span><br><span class="line"><span class="keyword">var</span> [itemx, ...newNames] = names</span><br><span class="line"><span class="built_in">console</span>.log(newNames) <span class="comment">// [&#x27;james&#x27;,&#x27;harden&#x27;]</span></span><br></pre></td></tr></table></figure></li>
<li><p>默认值</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 解构的默认值</span></span><br><span class="line"><span class="keyword">var</span> [itema, itemb, itemc, itemd = <span class="string">&#x27;kobe&#x27;</span>] = names</span><br><span class="line"><span class="built_in">console</span>.log(itemd) <span class="comment">// kobe</span></span><br></pre></td></tr></table></figure></li>
</ol>
<h3 id="对象的解构"><a href="#对象的解构" class="headerlink" title="对象的解构"></a>对象的解构</h3><ol>
<li><p>基本解构过程</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;curry&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">33</span>,</span><br><span class="line">  <span class="attr">height</span>: <span class="number">1.93</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> &#123; name, age, height &#125; = obj</span><br><span class="line"><span class="built_in">console</span>.log(name, age, height) <span class="comment">// &#x27;curry&#x27;,33,1.93</span></span><br></pre></td></tr></table></figure></li>
<li><p>任意顺序</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> &#123; age &#125; = obj</span><br><span class="line"><span class="built_in">console</span>.log(age) <span class="comment">// 33</span></span><br></pre></td></tr></table></figure></li>
<li><p>重命名</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> &#123; <span class="attr">name</span>: newName &#125; = obj</span><br><span class="line"><span class="built_in">console</span>.log(newName) <span class="comment">// &#x27;curry&#x27;</span></span><br></pre></td></tr></table></figure></li>
<li><p>默认值</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> &#123; <span class="attr">name</span>: newName = <span class="string">&quot;james&quot;</span> &#125; = obj</span><br><span class="line"><span class="built_in">console</span>.log(newName) <span class="comment">// &#x27;curry&#x27; 没有默认值是&#x27;james&#x27;</span></span><br></pre></td></tr></table></figure></li>
</ol>
<h2 id="let与const"><a href="#let与const" class="headerlink" title="let与const"></a>let与const</h2><p>在ES6之前，我们只能使用 <code>var</code> 关键字来声明变量，从从ES6开始新增了两个关键字可以声明变量：<code>let</code> 、<code>const</code> 。</p>
<h3 id="let关键字"><a href="#let关键字" class="headerlink" title="let关键字"></a>let关键字</h3><p>从直观的角度来说，let和var是没有太大的区别的，都是用于声明一个变量。</p>
<h3 id="const关键字"><a href="#const关键字" class="headerlink" title="const关键字"></a>const关键字</h3><p><code>const</code> 声明的变量一旦被赋值，就不能被修改，但是如果赋值的是 <strong>引用类型</strong> ，那么可以通过引用找到对应的对象，修改对象的内容。</p>
<h3 id="let与const的作用域提升"><a href="#let与const的作用域提升" class="headerlink" title="let与const的作用域提升"></a>let与const的作用域提升</h3><p>在 <a href="frontend/JavaScript/scope.md">运行原理与作用域 </a>中，我们知道 <code>var</code> 关键字是有变量提升的，但是如果我们使用 <code>let</code> 声明的变量，在声明之前访问会报错，因此 <code>let</code> 与 <code>const</code> 是没有作用域提升的。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(foo) <span class="comment">// Cannot access &#x27;foo&#x27; before initialization</span></span><br><span class="line"><span class="keyword">let</span> foo = <span class="number">1</span>;</span><br></pre></td></tr></table></figure>

<p>这并不意味着 <code>let</code> 声明的变量只有在代码执行阶段才会创建，根据 <code>ECMA262</code>规范的描述 <strong>这些变量会被创建在包含他们的词法环境被实例化时，但是是不可以访问它们的，直到词法绑定被求值</strong> 。</p>
<h3 id="window对象添加属性"><a href="#window对象添加属性" class="headerlink" title="window对象添加属性"></a>window对象添加属性</h3><p>我们知道使用 <code>var</code> 关键字声明的变量会在 <code>window</code> 对象中添加这个属性。</p>
<p>但是 <code>let</code> 和 <code>const</code> 不会给 <code>window</code> 对象添加属性。</p>
<p>那么这个变量保存在哪里呢？</p>
<p>在 <a href="frontend/JavaScript/scope.md">运行原理与作用域 </a>中，我们最后提到了最新的 <code>ECMA标准</code> 中对执行上下文的表述的变化：</p>
<blockquote>
<p>每一个执行上下文会关联到一个变量环境（<strong>variable Environment</strong>），在执行代码中变量和函数的声明会作为<strong>环境记录</strong>（Environment Record）添加到变量环境中。</p>
</blockquote>
<p>这就意味着我们声明的变量和环境记录是被添加到变量环境中的，这跟JS引擎的内部实现是有关系的。</p>
<p>比如V8引擎中是通过VariableMap的一个hashmap来实现它们的存储的。</p>
<p>而对于<code>window</code> 对象是早期的 <code>GO</code> 对象，在最新的实现中其实是浏览器添加的全局对象，并且一直保持了 <code>window</code> 和 <code>var</code> 之间值的相等性。</p>
<h3 id="块级作用域"><a href="#块级作用域" class="headerlink" title="块级作用域"></a>块级作用域</h3><p>在ES6之前，JavaScript只会形成两个作用域：全局作用域和函数作用域。</p>
<p>在ES6中新增了块级作用域，并且通过 <code>let</code>、<code>const</code>、<code>function</code>、<code>class</code> 声明的标识符是具备块级作用域的限制的：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="keyword">let</span> foo = <span class="string">&#x27;123&#x27;</span></span><br><span class="line">  <span class="built_in">console</span>.log(foo)</span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">bar</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;bar&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">bar() <span class="comment">// bar</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(foo) <span class="comment">// foo is not defined</span></span><br></pre></td></tr></table></figure>

<p>我们发现函数拥有块级作用域，但是外面依然是可以访问的：</p>
<p>这是因为引擎会对函数的声明进行特殊的处理，允许像 <code>var</code> 那样进行提升。</p>
<h3 id="暂时性死区"><a href="#暂时性死区" class="headerlink" title="暂时性死区"></a>暂时性死区</h3><p>在ES6中，我们还有一个概念称之为 <strong>暂时性死区</strong> ：</p>
<p>它表达的意思是在一个代码中，使用 <code>let</code> 、<code>const</code> 声明的变量，在声明之前，变量都是不可以访问的；</p>
<p>我们将这种现象称之为 <strong>temporal dead zone（暂时性死区，TDZ）</strong>。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> foo = <span class="string">&quot;123&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">  <span class="built_in">console</span>.log(foo) <span class="comment">// Cannot access &#x27;foo&#x27; before initialization</span></span><br><span class="line">  <span class="keyword">let</span> foo = <span class="string">&quot;456&quot;</span> </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="模板字符串"><a href="#模板字符串" class="headerlink" title="模板字符串"></a>模板字符串</h2><p>在ES6之前，如果我们想要将字符串和一些动态的变量（标识符）拼接到一起，是非常麻烦的。</p>
<p>在ES6中，我们可以使用模板字符串来嵌入 <strong>JS的表达式</strong> 来进行字符串的拼接：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">`my name is <span class="subst">$&#123;obj.name&#125;</span>, age is <span class="subst">$&#123;obj.age&#125;</span>`</span>)</span><br></pre></td></tr></table></figure>

<h3 id="标签模板字符串"><a href="#标签模板字符串" class="headerlink" title="标签模板字符串"></a>标签模板字符串</h3><p>模板字符串还有另外一种用法：标签模板字符串（Tagged Template Literals）。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params">...args</span>)</span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(args)</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> name = <span class="string">&#x27;curry&#x27;</span></span><br><span class="line"><span class="keyword">const</span> age = <span class="number">33</span></span><br><span class="line"></span><br><span class="line">foo<span class="string">`hello <span class="subst">$&#123;name&#125;</span> world <span class="subst">$&#123;age&#125;</span>`</span> <span class="comment">// [ [ &#x27;hello &#x27;, &#x27; world &#x27;, &#x27;&#x27; ], &#x27;curry&#x27;, 33 ]</span></span><br></pre></td></tr></table></figure>

<p>上面这个例子中，我们使用标签模板字符串，并且在调用的时候插入其他的变量，我们发现：</p>
<ul>
<li><p>模板字符串被拆分了。</p>
</li>
<li><p>第一个元素是数组，是被模块字符串拆分的字符串组合。</p>
</li>
<li><p>后面的元素是一个个模块字符串传入的内容。</p>
</li>
</ul>
<h2 id="函数相关"><a href="#函数相关" class="headerlink" title="函数相关"></a>函数相关</h2><h3 id="默认参数"><a href="#默认参数" class="headerlink" title="默认参数"></a>默认参数</h3><p>在ES6之前，我们编写的函数参数是没有默认值的，所以我们在编写函数时，如果有下面的需求： </p>
<ul>
<li><p>传入了参数，那么使用传入的参数；</p>
</li>
<li><p>没有传入参数，那么使用一个默认值；</p>
</li>
</ul>
<p>我们需要写出如下的代码：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> x = <span class="built_in">arguments</span>.length &gt; <span class="number">0</span> &amp;&amp; <span class="built_in">arguments</span>[<span class="number">0</span>] !== <span class="literal">undefined</span> ? <span class="built_in">arguments</span>[<span class="number">0</span>] : <span class="number">10</span>;</span><br><span class="line">  <span class="keyword">var</span> y = <span class="built_in">arguments</span>.length &gt; <span class="number">1</span> &amp;&amp; <span class="built_in">arguments</span>[<span class="number">1</span>] !== <span class="literal">undefined</span> ? <span class="built_in">arguments</span>[<span class="number">1</span>] : <span class="number">20</span>;</span><br><span class="line">  <span class="built_in">console</span>.log(x, y);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo();</span><br></pre></td></tr></table></figure>

<p>而在ES6中，我们可以给函数的参数以 <strong>默认值</strong> ：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params">x=<span class="number">10</span>,y=<span class="number">20</span></span>)</span>&#123;</span><br><span class="line">	<span class="built_in">console</span>.log(x,y)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo()</span><br></pre></td></tr></table></figure>

<p>默认值也可以和解构一起使用：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params">&#123; name, age &#125; = &#123;name:<span class="string">&#x27;curry&#x27;</span>,age:<span class="number">33</span>&#125;</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(name, age)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo() <span class="comment">// curry 33</span></span><br></pre></td></tr></table></figure>

<p>也可以这样写：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params">&#123; name = <span class="string">&#x27;curry&#x27;</span>, age = <span class="number">33</span> &#125; = &#123;&#125;</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(name, age)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo()</span><br></pre></td></tr></table></figure>

<h3 id="剩余参数"><a href="#剩余参数" class="headerlink" title="剩余参数"></a>剩余参数</h3><p>ES6中引用了 <strong>rest parameter（剩余参数）</strong>，可以将不定数量的参数放入到一个数组中。</p>
<blockquote>
<p>剩余参数必须放到最后一个位置，否则会报错。</p>
</blockquote>
<h4 id="剩余参数和arguments的区别"><a href="#剩余参数和arguments的区别" class="headerlink" title="剩余参数和arguments的区别"></a>剩余参数和arguments的区别</h4><ol>
<li><p>剩余参数只包含那些没有对应形参的实参，而 <code>arguments </code>对象包含了传给函数的所有实参。</p>
</li>
<li><p><code>arguments</code> 对象不是一个真正的数组，而 <code>rest</code> 参数是一个真正的数组，可以进行数组的所有操作。</p>
</li>
<li><p><code>arguments</code> 是早期的 <code> ECMAScript</code> 中为了方便去获取所有的参数提供的一个数据结构，而 <code>rest</code> 参数是ES6中提供 </p>
<p>并且希望以此来替代 <code>arguments</code> 的。</p>
</li>
</ol>
<h3 id="箭头函数"><a href="#箭头函数" class="headerlink" title="箭头函数"></a>箭头函数</h3><p>ES6提供了一种根据方便的编写函数的写法，叫做 <strong>箭头函数</strong> 。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> foo = <span class="function">() =&gt;</span> &#123;&#125;</span><br></pre></td></tr></table></figure>

<p>它与普通函数有如下差别：</p>
<ul>
<li><p>在<a href="frontend/JavaScript/this.md">this指向</a>中，我们提到过，**箭头函数没有自己的 <code>this</code>**，它只会向上层作用域查找 <code>this</code> 。</p>
</li>
<li><p>箭头函数没有显示原型，因此它也不能通过 <code>new</code> 关键字来调用。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">foo.prototype <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure></li>
<li><p>箭头函数只能通过表达式来声明</p>
</li>
</ul>
<h3 id="展开语法"><a href="#展开语法" class="headerlink" title="展开语法"></a>展开语法</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> names = [<span class="string">&quot;curry&quot;</span>, <span class="string">&quot;james&quot;</span>, <span class="string">&quot;harden&quot;</span>]</span><br><span class="line"><span class="keyword">const</span> name = <span class="string">&quot;messi&quot;</span></span><br><span class="line"><span class="keyword">const</span> obj = &#123;<span class="attr">name</span>: <span class="string">&quot;cr7&quot;</span>, <span class="attr">age</span>: <span class="number">37</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 1.函数调用时</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params">x, y, z</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(x, y, z)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo(...names)</span><br><span class="line">foo(...name)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2.构造数组时</span></span><br><span class="line"><span class="keyword">const</span> newNames = [...names, ...name]</span><br><span class="line"><span class="built_in">console</span>.log(newNames)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3.构建对象字面量时ES2018(ES9)</span></span><br><span class="line"><span class="keyword">const</span> obj = &#123; ...info, <span class="attr">address</span>: <span class="string">&quot;广州市&quot;</span>, ...names &#125;</span><br><span class="line"><span class="built_in">console</span>.log(obj)</span><br></pre></td></tr></table></figure>

<p>使用展开语法：</p>
<ul>
<li><p>可以在函数调用/数组构造时，将数组表达式或者字符串在语法层面展开；</p>
</li>
<li><p>还可以在构造字面量对象时, 将对象表达式按key-value的方式展开；</p>
</li>
</ul>
<p>展开语法的场景： </p>
<ul>
<li><p>在函数调用时使用；</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> names = [<span class="string">&quot;curry&quot;</span>, <span class="string">&quot;james&quot;</span>, <span class="string">&quot;harden&quot;</span>]</span><br><span class="line"><span class="keyword">const</span> name = <span class="string">&quot;messi&quot;</span></span><br><span class="line"><span class="keyword">const</span> info = &#123; <span class="attr">name</span>: <span class="string">&quot;curry&quot;</span>, <span class="attr">age</span>: <span class="number">33</span> &#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params">x, y, z</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(x, y, z)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">foo(...names) <span class="comment">// curry james harden</span></span><br><span class="line">foo(...name) <span class="comment">// m e s</span></span><br></pre></td></tr></table></figure></li>
<li><p>在数组构造时使用；</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> newNames = [...names, ...name]</span><br><span class="line"><span class="built_in">console</span>.log(newNames) <span class="comment">// [&#x27;curry&#x27;,&#x27;james&#x27;,&#x27;harden&#x27;],&#x27;m&#x27;,&#x27;e&#x27;,&#x27;s&#x27;,&#x27;s&#x27;,&#x27;i&#x27;]</span></span><br></pre></td></tr></table></figure></li>
<li><p>在构建对象字面量时，也可以使用展开运算符，这个是在ES2018（ES9）中添加的新特性；</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123; ...info, <span class="attr">team</span>: <span class="string">&quot;gsw&quot;</span>, ...names &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// &#123;</span></span><br><span class="line"><span class="comment">//   &#x27;0&#x27;: &#x27;curry&#x27;,</span></span><br><span class="line"><span class="comment">//   &#x27;1&#x27;: &#x27;james&#x27;,</span></span><br><span class="line"><span class="comment">//   &#x27;2&#x27;: &#x27;harden&#x27;,</span></span><br><span class="line"><span class="comment">//   name: &#x27;curry&#x27;,</span></span><br><span class="line"><span class="comment">//   age: 33,</span></span><br><span class="line"><span class="comment">//   team: &#x27;gsw&#x27;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(obj)</span><br></pre></td></tr></table></figure></li>
</ul>
<p>展开语法只是一种浅拷贝，下面这段代码中在内存表现大致如下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> foo = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;curry&#x27;</span>,</span><br><span class="line">  <span class="attr">friend</span>:&#123;</span><br><span class="line">    <span class="attr">name</span>:<span class="string">&#x27;kobe&#x27;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> bar = &#123;...foo&#125;</span><br><span class="line">foo.friend.name = <span class="string">&#x27;james&#x27;</span></span><br><span class="line"><span class="built_in">console</span>.log(bar.friend.name) <span class="comment">// james</span></span><br></pre></td></tr></table></figure>

<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20211208172052795.png" alt="image-20211208172052795"></p>
<p>可以看到：<code>foo</code> 和 <code>bar</code> 中的 <code>friend</code> 属性都指向同一个对象，这也证明了展开语法是一种浅拷贝的说法。</p>
<h2 id="数值的表示"><a href="#数值的表示" class="headerlink" title="数值的表示"></a>数值的表示</h2><p>ES6规范了二进制和八进制的写法：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> num2 = <span class="number">0b100</span> <span class="comment">// 二进制</span></span><br><span class="line"><span class="keyword">const</span> num3 = <span class="number">0o100</span> <span class="comment">// 八进制</span></span><br></pre></td></tr></table></figure>

<p>另外ES2021新增了如下特性：数字过长时，可以使用_作为连接符：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> num = <span class="number">10_000_000_000_000_000</span></span><br></pre></td></tr></table></figure>

<h2 id="Symbol"><a href="#Symbol" class="headerlink" title="Symbol"></a>Symbol</h2><p><code>Symbol</code> 是ES6中新增的一个基本数据类型，翻译为符号。</p>
<p>为什么需要 <code>Symbol</code> ？</p>
<ul>
<li><p>在ES6之前，对象的属性名其实都是<strong>字符串形式</strong>，那么很容易造成属性名的冲突。</p>
</li>
<li><p>如果原来有一个对象，我们希望在其中添加一个新的属性和值，但是我们在不确定它原来内部有什么内容的情况下，很容易造成冲突，从而<strong>覆盖掉它内部的某个属性</strong>。</p>
</li>
<li><p>开发中我们如果使用混入，那么混入中出现了<strong>同名的属性</strong>，必然有一个会被覆盖掉。</p>
</li>
</ul>
<p>我们可以发现：<code>Sybmol</code> 其实就是用来 <strong>生成一个独一无二的值</strong> 。</p>
<p>Symbol函数执行后每次创建出来的值都是独一无二的，<strong>我们也可以在创建Symbol值的时候传入一个描述description</strong>：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> s1 = <span class="built_in">Symbol</span>()</span><br><span class="line"><span class="keyword">const</span> s2 = <span class="built_in">Symbol</span>()</span><br><span class="line"><span class="keyword">const</span> s3 = <span class="built_in">Symbol</span>(<span class="string">&#x27;abc&#x27;</span>)</span><br><span class="line"><span class="built_in">console</span>.log(s1 === s2)</span><br></pre></td></tr></table></figure>

<p>我们可以使用 <code>Symbol</code> 来作为属性名，有三种方式：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1.定义字面量直接使用</span></span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  [s3]:<span class="string">&#x27;james&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2.属性名赋值</span></span><br><span class="line">obj[s3] = <span class="string">&#x27;james&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 3.Object.defineProperty</span></span><br><span class="line"><span class="built_in">Object</span>.defineProperty(obj,s3,&#123;</span><br><span class="line">  <span class="attr">value</span>:<span class="string">&#x27;james&#x27;</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>如果我们想通过 <code>Symbol</code> 创建相同的值，可以使用 <code>Symbol.for() </code>这个函数。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> s4 = <span class="built_in">Symbol</span>.for(<span class="string">&#x27;abc&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> s5 = <span class="built_in">Symbol</span>.for(<span class="string">&#x27;abc&#x27;</span>)</span><br><span class="line"><span class="built_in">console</span>.log(s4 === s5) <span class="comment">// true</span></span><br></pre></td></tr></table></figure>

<p>也可以使用 <code>Symbol.keyFor()</code> 这个函数来得到 <code>Symbol</code> 的 描述。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> s4 = <span class="built_in">Symbol</span>.for(<span class="string">&#x27;abc&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> s5 = <span class="built_in">Symbol</span>.for(<span class="string">&#x27;abc&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> key = <span class="built_in">Symbol</span>.keyFor(s5) <span class="comment">// &#x27;abc&#x27;</span></span><br><span class="line"><span class="keyword">const</span> s6 = <span class="built_in">Symbol</span>.for(key)</span><br><span class="line"><span class="built_in">console</span>.log(s4 === s5) <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(s4 === s6) <span class="comment">// true</span></span><br></pre></td></tr></table></figure>

<h2 id="Set"><a href="#Set" class="headerlink" title="Set"></a>Set</h2><p>在ES6之前，我们存储数据的结构主要有两种：数组和对象，</p>
<p>ES6新增了两种数据结构：<code>Set</code> 、 <code>Map</code> 以及它们的另外的形式 <code>WeakSet</code> 、 <code>WeakMap</code> 。</p>
<p><code>Set</code> 用来保存数据，类似于数组，但是和数组的区别是 <strong>元素不能重复</strong> 。</p>
<h3 id="创建Set"><a href="#创建Set" class="headerlink" title="创建Set"></a>创建Set</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建Set</span></span><br><span class="line"><span class="keyword">const</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>()</span><br><span class="line">set.add(<span class="number">1</span>)</span><br><span class="line">set.add(<span class="number">2</span>)</span><br><span class="line">set.add(<span class="number">1</span>)</span><br><span class="line"><span class="built_in">console</span>.log(set) <span class="comment">// Set(2) &#123; 1, 2 &#125;</span></span><br></pre></td></tr></table></figure>

<h3 id="数组去重"><a href="#数组去重" class="headerlink" title="数组去重"></a>数组去重</h3><p>在没有 <code>Set</code> 之前，如果需要进行数组去重，我们需要写出这样的代码：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">4</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> newArr = []</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; arr.length; i++) &#123;</span><br><span class="line">  <span class="keyword">if</span> (newArr.indexOf(arr[i]) === -<span class="number">1</span>) &#123;</span><br><span class="line">    newArr.push(arr[i])</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log(newArr)</span><br></pre></td></tr></table></figure>

<p>在有了 <code>Set</code> 之后，我们可以这样实现：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">4</span>]</span><br><span class="line"><span class="keyword">const</span> newArr = [...(<span class="keyword">new</span> <span class="built_in">Set</span>(arr))]</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(newArr) <span class="comment">// [ 1, 2, 4 ]</span></span><br></pre></td></tr></table></figure>

<p>看起来简洁了很多。</p>
<h3 id="Set常见的属性和方法"><a href="#Set常见的属性和方法" class="headerlink" title="Set常见的属性和方法"></a>Set常见的属性和方法</h3><h4 id="常见属性"><a href="#常见属性" class="headerlink" title="常见属性"></a>常见属性</h4><ul>
<li><code>size</code>：返回 <code>Set</code> 中元素的个数。</li>
</ul>
<h4 id="常见方法"><a href="#常见方法" class="headerlink" title="常见方法"></a>常见方法</h4><ul>
<li><code>add(value)</code>：添加某个元素，返回 <code>Set</code> 对象本身。</li>
<li><code>delete(value)</code>：从 <code>Set</code> 中删除和这个值相等的元素，返回 <code>boolean</code> 类型。</li>
<li><code>has(value)</code>：判断 <code>set</code> 中是否存在某个元素，返回 <code>boolean</code>  类型。</li>
<li><code>clear()</code>：清空 <code>Set</code> 中所有的元素，没有返回值。</li>
<li><code>forEach(callback, [, thisArg])</code>：通过 <code>forEach</code> 遍历 <code>Set</code> 。</li>
<li>Set也支持 <code>for of</code> 遍历。</li>
</ul>
<h2 id="WeakSet"><a href="#WeakSet" class="headerlink" title="WeakSet"></a>WeakSet</h2><p>和 <code>Set</code> 类似的另外一个数据结构称之为 <code>WeakSet</code> ，也是内部元素不能重复的数据结构。</p>
<h3 id="WeakSet和Set的区别"><a href="#WeakSet和Set的区别" class="headerlink" title="WeakSet和Set的区别"></a>WeakSet和Set的区别</h3><ol>
<li><code>WeakSet</code> 中只能存放对象类型，不能存放基本数据类型。</li>
<li><code>WeakSet</code> <strong>对元素的引用是弱引用</strong>（后面会说什么是弱引用），如果没有其他引用对某个对象进行引用，那么 <code>GC（垃圾回收器）</code> 可以对该对象进行回收。</li>
</ol>
<p>常见方法：</p>
<ol>
<li><p><code>add(value)</code>：添加某个元素，返回 <code>WeakSet</code> 对象本身。</p>
</li>
<li><p><code>delete(value)</code>：从 <code>WeakSet</code> 中删除和这个值相等的元素，返回 <code>boolean</code> 类型。</p>
</li>
<li><p><code>has(value)</code>：判断 <code>WeakSet</code> 中是否存在某个元素，返回 <code>boolean</code> 类型。</p>
</li>
</ol>
<h3 id="WeakSet中对元素的引用是弱引用"><a href="#WeakSet中对元素的引用是弱引用" class="headerlink" title="WeakSet中对元素的引用是弱引用"></a>WeakSet中对元素的引用是弱引用</h3><p>我们上面提到，<code>WeakSet</code> 对元素的引用是弱引用，那么什么是弱引用呢？通过一个例子我们来认识一下：</p>
<p>如果我们使用 <code>Set</code> 来存放对象类型，那么它在内存表现是这样的<strong>（红色的线代表强引用）</strong>：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;curry&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">33</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>()</span><br><span class="line">set.add(obj)</span><br></pre></td></tr></table></figure>

<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20211208230549399.png" alt="image-20211208230549399"></p>
<p>而使用 <code>WeakSet</code> 来存放对象类型的数据，它的内存表现是这样的<strong>（红色的线代表强引用，黄色的线代表弱引用）</strong>：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;curry&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">33</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> wset = <span class="keyword">new</span> <span class="built_in">WeakSet</span>()</span><br><span class="line">wset.add(obj)</span><br></pre></td></tr></table></figure>

<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20211208230722876.png" alt="image-20211208230722876"></p>
<p>我们上面介绍了：</p>
<blockquote>
<p><code>WeakSet</code> <strong>对元素的引用是弱引用</strong>，如果没有其他引用对某个对象进行引用，那么 <code>GC（垃圾回收器）</code> 可以对该对象进行回收。</p>
</blockquote>
<p><strong>这也就意味着：</strong></p>
<p>如果我们使用 <code>Set</code> 存放对象类型，当我们将 <code>obj</code> 赋值为 <code>null</code> ，虽然 <code>obj</code> 不再指向 <code>0xa00</code> 这个内存空间，但是 <code>set变量</code> 中的一个元素仍然保存着 <code>0xa00</code> 的引用（由于它是强引用），因此，<code>0xa00</code> 这块内存空间仍然不会被 <code>GC</code> 回收。</p>
<p>如果我们使用 <code>WeakSet</code> 存放对象类型，当我们将 <code>obj</code> 赋值为 <code>null</code> ， <code>obj</code> 不再指向 <code>0xa00</code> 这个内存空间。并且，由于 <code>WeakSet</code> 保存的元素的引用是弱引用，因此，<code>WeakSet</code> 不再保存对这块内存空间的引用， <code>0xa00</code> 这块内存空间将会被 <code>GC</code> 回收。</p>
<h3 id="WeakSet的应用场景"><a href="#WeakSet的应用场景" class="headerlink" title="WeakSet的应用场景"></a>WeakSet的应用场景</h3><p>事实上，<code>WeakSet</code> 的应用场景并不多。</p>
<p>如果我们需要判断一个对象是否是通过自己的实例来调用该对象内部的方法，我们可以使用 <code>WeakSet</code> ：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> pwset = <span class="keyword">new</span> <span class="built_in">WeakSet</span>()</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">    pwset.add(<span class="built_in">this</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="title">running</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (!pwset.has(<span class="built_in">this</span>)) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">&#x27;不能通过其他对象调用running方法&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;running&#x27;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> p = <span class="keyword">new</span> Person()</span><br><span class="line"></span><br><span class="line">p.running() <span class="comment">// running</span></span><br><span class="line">p.running.call(&#123; <span class="attr">name</span>: <span class="string">&#x27;curry&#x27;</span> &#125;) <span class="comment">// error</span></span><br></pre></td></tr></table></figure>

<h2 id="Map"><a href="#Map" class="headerlink" title="Map"></a>Map</h2><p>另外一个新增的数据结构是 <code>Map</code> ，用于存储映射关系。</p>
<h3 id="Map与普通对象的区别"><a href="#Map与普通对象的区别" class="headerlink" title="Map与普通对象的区别"></a>Map与普通对象的区别</h3><p>对于对象来说：</p>
<ul>
<li>存储映射关系只能用字符串（ES6新增了Symbol）作为属性名（key）。</li>
<li>某些情况下我们可能希望通过其他类型作为key，比如对象，这个时候会自动将对象转成字符串来作为key。</li>
</ul>
<p>遇到这种情况，我们可以使用 <code>Map</code> 。</p>
<h3 id="Map的常见属性和方法"><a href="#Map的常见属性和方法" class="headerlink" title="Map的常见属性和方法"></a>Map的常见属性和方法</h3><h4 id="常见属性-1"><a href="#常见属性-1" class="headerlink" title="常见属性"></a>常见属性</h4><ul>
<li><code>size</code> ： 返回 <code>Map</code> 中元素的个数。</li>
</ul>
<h4 id="常见方法-1"><a href="#常见方法-1" class="headerlink" title="常见方法"></a>常见方法</h4><ul>
<li><code>set(key,value)</code> ：在 <code>Map</code> 中添加 <code>key</code> 、 <code>value</code> ，并且返回整个 <code>Map</code> 对象。</li>
<li><code>get(key)</code> ：根据 <code>key</code> 获取 <code>Map</code> 对象中的 <code>value</code> 。</li>
<li><code>has(key)</code> ：判断是否包括某一个 <code>key</code> ，返回 <code>boolean</code> 类型。</li>
<li><code>delete(key)</code> ：根据 <code>key</code> 删除一个键值对，返回 <code>boolean</code> 类型。</li>
<li><code>clear()</code> ：清空所有元素</li>
<li><code>forEach(callback,[,thisArg])</code> ：通过 <code>forEach</code> 遍历 <code>Map</code> 。</li>
<li><code>Map</code> 也支持通过 <code>for of</code> 遍历。</li>
</ul>
<h2 id="WeakMap"><a href="#WeakMap" class="headerlink" title="WeakMap"></a>WeakMap</h2><p>和 <code>Map</code> 类型相似的另外一个数据结构称之为 <code>WeakMap</code> ，也是以键值对的形式存在的。</p>
<h3 id="WeakMap和Map的区别"><a href="#WeakMap和Map的区别" class="headerlink" title="WeakMap和Map的区别"></a>WeakMap和Map的区别</h3><ol>
<li><code>WeakMap</code> 的 <code>key</code> 只能使用对象，不接受其他的类型作为 <code>key</code> 。</li>
<li><code>WeakMap</code> 的 <code>key</code> 对对象的引用是弱引用，如果没有其他引用引用这个对象，那么 <code>GC</code> 可以回收该对象。</li>
<li><code>WeakMap</code> 不能遍历，因为没有 <code>forEach</code> 方法，也不支持通过 <code>for of</code> 的方式进行遍历。</li>
</ol>
<h3 id="WeakMap的常见方法"><a href="#WeakMap的常见方法" class="headerlink" title="WeakMap的常见方法"></a>WeakMap的常见方法</h3><ul>
<li><code>set(key, value)</code> ：在 <code>Map</code> 中添加 <code>key</code> 、<code>value</code> ，并且返回整个 <code>Map</code> 对象。</li>
<li><code>get(key)</code> ：根据 <code>key</code> 获取 <code>Map</code> 中的 <code>value</code> 。</li>
<li><code>has(key)</code> ：判断是否包括某一个 <code>key</code> ，返回 <code>boolean</code> 类型。</li>
<li><code>delete(key)</code> ：根据 <code>key</code> 删除一个键值对，返回 <code>boolean</code> 类型。</li>
</ul>
<h3 id="WeakMap的应用场景"><a href="#WeakMap的应用场景" class="headerlink" title="WeakMap的应用场景"></a>WeakMap的应用场景</h3><p>在 <code>Vue</code> 的响应式原理中，其实就使用了 <code>WeakMap</code>。</p>
<p>看下面这个例子：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj1 = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;curry&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">30</span>,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">objNameFn1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">&#x27;objNameFn1被执行了&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">objNameFn2</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">&#x27;objNameFn2被执行了&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">obj1AgeFn1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">&#x27;objAgeFn1被执行了&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">obj1AgeFn2</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">&#x27;objAgeFn2被执行了&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> weakMap = <span class="keyword">new</span> <span class="built_in">WeakMap</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj1Map = <span class="keyword">new</span> <span class="built_in">Map</span>()</span><br><span class="line">obj1Map.set(<span class="string">&#x27;name&#x27;</span>, [objNameFn1, objNameFn2])</span><br><span class="line">obj1Map.set(<span class="string">&#x27;age&#x27;</span>, [obj1AgeFn1, obj1AgeFn2])</span><br><span class="line"></span><br><span class="line">weakMap.set(obj,obj1Map)</span><br><span class="line"></span><br><span class="line"><span class="comment">// obj1.name 发生了改变</span></span><br><span class="line"><span class="comment">// vue 通过 proxy 和 Object.defineProperty 监听变化 </span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过 WeakMap 实现响应式变化</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取到要变化的那个对象（obj1）中的所有属性</span></span><br><span class="line"><span class="keyword">const</span> targetMap = weakMap.get(obj1)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 根据要变化的那个属性 获取到所有改变这个属性值的方法</span></span><br><span class="line"><span class="keyword">const</span> nameFns = targetMap.get(<span class="string">&quot;name&quot;</span>) </span><br><span class="line"></span><br><span class="line"><span class="comment">// 执行方法对属性进行响应式更改</span></span><br><span class="line">nameFns.forEach(<span class="function"><span class="params">item</span> =&gt;</span> item())</span><br></pre></td></tr></table></figure>

<p>在上面这个例子中，<code>WeakMap</code> 做的事情就是保存 <code>obj1</code> 这个对象的引用，当通过 <code>proxy</code> 和 <code>Object.defineProperty</code> 监听到属性的变化，就将该对象中的属性响应式的方法获取并对其调用。 </p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>以上就是ES6中的一些知识点，其中还有不少知识点，例如：<code>Promise</code> 、 <code>迭代器</code> 等知识我们将会在另外的章节对其进行总结。</p>
<p>ES6是JavaScript的一个更新相当大的版本，知识点较多，ES6之后的版本相对来说会少很多东西。</p>

  </div>
</article>



        
          <div id="footer-post-container">
  <div id="footer-post">

    <div id="nav-footer" style="display: none">
      <ul>
         
          <li><a href="/">首页</a></li>
         
          <li><a href="/tags/">标签</a></li>
         
          <li><a href="/categories/">分类</a></li>
         
          <li><a href="/archives/">归档</a></li>
         
          <li><a target="_blank" rel="noopener" href="http://github.com/twitzz">项目</a></li>
         
          <li><a href="/about/">关于</a></li>
         
          <li><a href="/search/">搜索</a></li>
        
      </ul>
    </div>

    <div id="toc-footer" style="display: none">
      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#class%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">1.</span> <span class="toc-text">class关键字</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E5%AE%9A%E4%B9%89%E7%B1%BB"><span class="toc-number">1.1.</span> <span class="toc-text">如何定义类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0"><span class="toc-number">1.2.</span> <span class="toc-text">类的构造函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E5%AE%9E%E4%BE%8B%E6%96%B9%E6%B3%95"><span class="toc-number">1.3.</span> <span class="toc-text">类的实例方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E8%AE%BF%E9%97%AE%E5%99%A8%E6%96%B9%E6%B3%95"><span class="toc-number">1.4.</span> <span class="toc-text">类的访问器方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95"><span class="toc-number">1.5.</span> <span class="toc-text">类的静态方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#ES6%E4%B8%AD%E7%B1%BB%E7%9A%84%E7%BB%A7%E6%89%BF%EF%BC%88extends%EF%BC%89"><span class="toc-number">1.6.</span> <span class="toc-text">ES6中类的继承（extends）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#super%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">1.7.</span> <span class="toc-text">super关键字</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%A7%E6%89%BF%E5%86%85%E7%BD%AE%E7%B1%BB"><span class="toc-number">1.8.</span> <span class="toc-text">继承内置类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E6%B7%B7%E5%85%A5%EF%BC%88mixin%EF%BC%89"><span class="toc-number">1.9.</span> <span class="toc-text">类的混入（mixin）</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AD%97%E9%9D%A2%E9%87%8F%E7%9A%84%E5%A2%9E%E5%BC%BA"><span class="toc-number">2.</span> <span class="toc-text">字面量的增强</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%9E%E6%80%A7%E7%9A%84%E7%AE%80%E5%86%99"><span class="toc-number">2.1.</span> <span class="toc-text">属性的简写</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%96%B9%E6%B3%95%E7%9A%84%E7%AE%80%E5%86%99"><span class="toc-number">2.2.</span> <span class="toc-text">方法的简写</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7%E5%90%8D"><span class="toc-number">2.3.</span> <span class="toc-text">计算属性名</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A7%A3%E6%9E%84"><span class="toc-number">3.</span> <span class="toc-text">解构</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E7%BB%84%E7%9A%84%E8%A7%A3%E6%9E%84"><span class="toc-number">3.1.</span> <span class="toc-text">数组的解构</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E7%9A%84%E8%A7%A3%E6%9E%84"><span class="toc-number">3.2.</span> <span class="toc-text">对象的解构</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#let%E4%B8%8Econst"><span class="toc-number">4.</span> <span class="toc-text">let与const</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#let%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">4.1.</span> <span class="toc-text">let关键字</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#const%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">4.2.</span> <span class="toc-text">const关键字</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#let%E4%B8%8Econst%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%8F%90%E5%8D%87"><span class="toc-number">4.3.</span> <span class="toc-text">let与const的作用域提升</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#window%E5%AF%B9%E8%B1%A1%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7"><span class="toc-number">4.4.</span> <span class="toc-text">window对象添加属性</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9D%97%E7%BA%A7%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">4.5.</span> <span class="toc-text">块级作用域</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9A%82%E6%97%B6%E6%80%A7%E6%AD%BB%E5%8C%BA"><span class="toc-number">4.6.</span> <span class="toc-text">暂时性死区</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A8%A1%E6%9D%BF%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-number">5.</span> <span class="toc-text">模板字符串</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A0%87%E7%AD%BE%E6%A8%A1%E6%9D%BF%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-number">5.1.</span> <span class="toc-text">标签模板字符串</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%9B%B8%E5%85%B3"><span class="toc-number">6.</span> <span class="toc-text">函数相关</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%BB%98%E8%AE%A4%E5%8F%82%E6%95%B0"><span class="toc-number">6.1.</span> <span class="toc-text">默认参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0"><span class="toc-number">6.2.</span> <span class="toc-text">剩余参数</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0%E5%92%8Carguments%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">6.2.1.</span> <span class="toc-text">剩余参数和arguments的区别</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0"><span class="toc-number">6.3.</span> <span class="toc-text">箭头函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%95%E5%BC%80%E8%AF%AD%E6%B3%95"><span class="toc-number">6.4.</span> <span class="toc-text">展开语法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%B0%E5%80%BC%E7%9A%84%E8%A1%A8%E7%A4%BA"><span class="toc-number">7.</span> <span class="toc-text">数值的表示</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Symbol"><span class="toc-number">8.</span> <span class="toc-text">Symbol</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Set"><span class="toc-number">9.</span> <span class="toc-text">Set</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9B%E5%BB%BASet"><span class="toc-number">9.1.</span> <span class="toc-text">创建Set</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E7%BB%84%E5%8E%BB%E9%87%8D"><span class="toc-number">9.2.</span> <span class="toc-text">数组去重</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Set%E5%B8%B8%E8%A7%81%E7%9A%84%E5%B1%9E%E6%80%A7%E5%92%8C%E6%96%B9%E6%B3%95"><span class="toc-number">9.3.</span> <span class="toc-text">Set常见的属性和方法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E8%A7%81%E5%B1%9E%E6%80%A7"><span class="toc-number">9.3.1.</span> <span class="toc-text">常见属性</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E8%A7%81%E6%96%B9%E6%B3%95"><span class="toc-number">9.3.2.</span> <span class="toc-text">常见方法</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#WeakSet"><span class="toc-number">10.</span> <span class="toc-text">WeakSet</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakSet%E5%92%8CSet%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">10.1.</span> <span class="toc-text">WeakSet和Set的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakSet%E4%B8%AD%E5%AF%B9%E5%85%83%E7%B4%A0%E7%9A%84%E5%BC%95%E7%94%A8%E6%98%AF%E5%BC%B1%E5%BC%95%E7%94%A8"><span class="toc-number">10.2.</span> <span class="toc-text">WeakSet中对元素的引用是弱引用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakSet%E7%9A%84%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">10.3.</span> <span class="toc-text">WeakSet的应用场景</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Map"><span class="toc-number">11.</span> <span class="toc-text">Map</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Map%E4%B8%8E%E6%99%AE%E9%80%9A%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">11.1.</span> <span class="toc-text">Map与普通对象的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Map%E7%9A%84%E5%B8%B8%E8%A7%81%E5%B1%9E%E6%80%A7%E5%92%8C%E6%96%B9%E6%B3%95"><span class="toc-number">11.2.</span> <span class="toc-text">Map的常见属性和方法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E8%A7%81%E5%B1%9E%E6%80%A7-1"><span class="toc-number">11.2.1.</span> <span class="toc-text">常见属性</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B8%B8%E8%A7%81%E6%96%B9%E6%B3%95-1"><span class="toc-number">11.2.2.</span> <span class="toc-text">常见方法</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#WeakMap"><span class="toc-number">12.</span> <span class="toc-text">WeakMap</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakMap%E5%92%8CMap%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">12.1.</span> <span class="toc-text">WeakMap和Map的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakMap%E7%9A%84%E5%B8%B8%E8%A7%81%E6%96%B9%E6%B3%95"><span class="toc-number">12.2.</span> <span class="toc-text">WeakMap的常见方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WeakMap%E7%9A%84%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">12.3.</span> <span class="toc-text">WeakMap的应用场景</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%BB%E7%BB%93"><span class="toc-number">13.</span> <span class="toc-text">总结</span></a></li></ol>
    </div>

    <div id="share-footer" style="display: none">
      <ul>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/"><i class="fab fa-facebook fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&text=ES6"><i class="fab fa-twitter fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-linkedin fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&is_video=false&description=ES6"><i class="fab fa-pinterest fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=ES6&body=Check out this article: https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/"><i class="fas fa-envelope fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-get-pocket fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-reddit fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-stumbleupon fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&title=ES6"><i class="fab fa-digg fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&name=ES6&description="><i class="fab fa-tumblr fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://danyuan30.gitee.io/2022/02/05/JavaScript/ES6/&t=ES6"><i class="fab fa-hacker-news fa-lg" aria-hidden="true"></i></a></li>
</ul>

    </div>

    <div id="actions-footer">
        <a id="menu" class="icon" href="#" onclick="$('#nav-footer').toggle();return false;"><i class="fas fa-bars fa-lg" aria-hidden="true"></i> 菜单</a>
        <a id="toc" class="icon" href="#" onclick="$('#toc-footer').toggle();return false;"><i class="fas fa-list fa-lg" aria-hidden="true"></i> 目录</a>
        <a id="share" class="icon" href="#" onclick="$('#share-footer').toggle();return false;"><i class="fas fa-share-alt fa-lg" aria-hidden="true"></i> 分享</a>
        <a id="top" style="display:none" class="icon" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fas fa-chevron-up fa-lg" aria-hidden="true"></i> 返回顶部</a>
    </div>

  </div>
</div>

        
        <footer id="footer">
  <div class="footer-left">
    Copyright &copy;
    
    
    2021-2022
    柯里的语法糖
  </div>
  <div class="footer-right">
    <nav>
      <ul>
        <!--
       --><li><a href="/">首页</a></li><!--
     --><!--
       --><li><a href="/tags/">标签</a></li><!--
     --><!--
       --><li><a href="/categories/">分类</a></li><!--
     --><!--
       --><li><a href="/archives/">归档</a></li><!--
     --><!--
       --><li><a target="_blank" rel="noopener" href="http://github.com/twitzz">项目</a></li><!--
     --><!--
       --><li><a href="/about/">关于</a></li><!--
     --><!--
       --><li><a href="/search/">搜索</a></li><!--
     -->
      </ul>
    </nav>
  </div>
</footer>

    </div>
    <!-- styles -->



  <link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" crossorigin="anonymous" onload="this.onload=null;this.rel='stylesheet'"/>


    <!-- jquery -->
 
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script> 




<!-- clipboard -->

  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.7/clipboard.min.js" crossorigin="anonymous"></script> 
  
  <script type="text/javascript">
  $(function() {
    // copy-btn HTML
    var btn = "<span class=\"btn-copy tooltipped tooltipped-sw\" aria-label=\"复制到粘贴板!\">";
    btn += '<i class="far fa-clone"></i>';
    btn += '</span>'; 
    // mount it!
    $(".highlight table").before(btn);
    var clip = new ClipboardJS('.btn-copy', {
      text: function(trigger) {
        return Array.from(trigger.nextElementSibling.querySelectorAll('.code')).reduce((str,it)=>str+it.innerText+'\n','')
      }
    });
    clip.on('success', function(e) {
      e.trigger.setAttribute('aria-label', "复制成功!");
      e.clearSelection();
    })
  })
  </script>


<script src="/js/main.js"></script>

<!-- search -->

<!-- Google Analytics -->

<!-- Baidu Analytics -->

<!-- Cloudflare Analytics -->

<!-- Umami Analytics -->

<!-- Disqus Comments -->

<!-- utterances Comments -->

</body>
</html>
